package com.miplus.ccrm.core.api.dify;

import cn.hutool.core.util.EscapeUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.miplus.ccrm.core.api.dify.model.BlockResponse;
import com.miplus.ccrm.core.api.dify.model.DifyChatRequest;
import com.miplus.ccrm.core.api.dify.model.DifyConstant;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
import reactor.core.publisher.Flux;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.HashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

@RequiredArgsConstructor
@Slf4j
@Service
public class DifyService {

    private static final String url = "http://154.36.158.37/v1/chat-messages";

    private final RestTemplate restTemplate;

    private final WebClient webClient;

    /**
     * 流式调用dify.
     *
     * @return Flux 响应流
     */
    public Flux<String> streamingMessage(DifyChatRequest request) {
        //1.设置请求体
        DifyChatRequest body = new DifyChatRequest();
        // 根据智能助手的ID选择不同的智能助手,不同的助手apiKey  类似 xj 、zdy
        String agentId = request.getAgent_id();
        body.setInputs(request.getInputs());
        body.setQuery(request.getQuery());
        body.setResponse_mode("streaming");
        body.setConversation_id(request.getConversation_id());
        body.setUser(request.getUser());
         log.info("dify请求参数：{}", JSONUtil.toJsonStr(body));
        String apiKey = null;
        switch (agentId) {
            case "jjy":
                apiKey = DifyConstant.DIFY_JC_STEAM_KEY; //禁忌语检测
                break;
            case "zdy":
                apiKey = DifyConstant.DIFY_XJ_ZDY_KEY; //自定义提示词
                break;
            case "xj":
                apiKey = DifyConstant.DIFY_XJ_KEY; //小结
                break;
            case "rag":
                apiKey = DifyConstant.DIFY_RAG_KEY; //rag辅助助手
                break;
            case "hsfz":
                apiKey = DifyConstant.DIFY_HSFZ_STEAM_KEY; //话术辅助
                break;
            default:                                 //默认api 测试
                apiKey = DifyConstant.DIFY_KEY;
                break;
        }
        //2.使用webclient发送post请求
        String finalApiKey = apiKey;
        StringBuilder fullAnswerBuilder = new StringBuilder();
        return webClient.post()
                .uri(url)
                .headers(httpHeaders -> {
                    httpHeaders.setContentType(MediaType.APPLICATION_JSON);
                    httpHeaders.setBearerAuth(finalApiKey);
                })
                .bodyValue(JSONUtil.toJsonStr(body))
                .retrieve()
                .bodyToFlux(String.class)
                // 添加这行来打印每个流片段
                //.doOnNext(sse -> log.info("dify流片段: {}", sse));
                // 处理每个流片段：解析JSON、解码Unicode、拼接
                .doOnNext(sseFragment -> {
                    try {
                        // 1. 用Hutool解析JSON片段
                        JSONObject sseJson = JSONUtil.parseObj(sseFragment);
                        String rawAnswer = sseJson.getStr("answer");
                        if (StrUtil.isEmpty(rawAnswer)) {
                            return;
                        }
                        // 2. 解码Unicode
                        String decodedAnswer = EscapeUtil.unescape(rawAnswer);
                        // 3. 拼接当前片段到完整结果
                        fullAnswerBuilder.append(decodedAnswer);

                        // 打印解码后的当前片段（调试用）
                        log.info("Dify流片段: {}", sseFragment);
                    } catch (Exception e) {
                        log.error("处理Dify流片段失败，原始片段: {}", sseFragment, e);
                    }
                })
                // 流结束时打印完整结果
                .doOnComplete(() -> {
                    String fullAnswer = fullAnswerBuilder.toString();
                    log.info("Dify完整Answer: \n{}", fullAnswer);
                })
                // 异常时打印已拼接的部分结果
                .doOnError(error -> {
                    log.error("Dify接口调用异常:", error);
                });
    }


    /**
     * 阻塞式调用dify.

     * @return BlockResponse
     */
    public BlockResponse blockingMessage(DifyChatRequest request) {
        //1.设置请求体
        DifyChatRequest body = new DifyChatRequest();
        // 根据智能助手的ID选择不同的智能助手,不同的助手apiKey  类似 xj 、zdy
        String agentId = request.getAgent_id();
        HashMap<String, String> inputs = new HashMap<>();
        body.setInputs(inputs);
        body.setQuery(request.getQuery());
        body.setResponse_mode("blocking");
        body.setConversation_id(request.getConversation_id());
        body.setUser(request.getUser());
        //2.设置请求头
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
        switch (agentId) {
            case "xj":    //小结
                headers.setBearerAuth(DifyConstant.DIFY_XJ_KEY);
                break;
            case "zdy":   //自定义
                headers.setBearerAuth(DifyConstant.DIFY_XJ_ZDY_KEY);
                break;
            case "hsfz":
                headers.setBearerAuth(DifyConstant.DIFY_HSFZ_KEY); //话术辅助
                break;
            case "jjy":
                headers.setBearerAuth(DifyConstant.DIFY_JC_KEY); //禁忌语检测
                break;
            default:
                headers.setBearerAuth(DifyConstant.DIFY_KEY);
                break;
        }
        //3.封装请求体和请求头
        String jsonString = JSONUtil.toJsonStr(body);
        HttpEntity<String> entity = new HttpEntity<>(jsonString, headers);
        //4.发送post请求，阻塞式
        ResponseEntity<BlockResponse> stringResponseEntity =
                restTemplate.postForEntity(url, entity, BlockResponse.class);
        //5.返回响应体
        log.info("dify响应结果：{}", JSONUtil.toJsonStr(stringResponseEntity.getBody()));
        //打印AI回复的文本
        log.info("dify回复：{}", cleanCodeBlock(stringResponseEntity.getBody().getAnswer()));
        return stringResponseEntity.getBody();
    }

    public SseEmitter sendChatMessage(DifyChatRequest chatMessageDto) {
        // 创建 SSE Emitter，设置超时时间（例如 5 分钟）
        SseEmitter emitter = new SseEmitter(300_000L);
        // 使用线程池处理异步任务
        ExecutorService executor = Executors.newSingleThreadExecutor();
        executor.execute(() -> {
            try {
                String messageUrl = url;

                // 创建请求头
                HttpHeaders headers = new HttpHeaders();
                headers.set("Authorization", "Bearer " + DifyConstant.DIFY_KEY);
                headers.setContentType(MediaType.APPLICATION_JSON);

                // 创建请求实体
                HttpEntity<DifyChatRequest> requestEntity = new HttpEntity<>(chatMessageDto, headers);
                log.info("dify请求参数：{}", JSONUtil.toJsonStr(chatMessageDto));
                // 发送请求并处理流式响应
                restTemplate.execute(
                        messageUrl,
                        HttpMethod.POST,
                        request -> {
                            // 设置请求头和请求体
                            request.getHeaders().setContentType(MediaType.APPLICATION_JSON);
                            request.getHeaders().addAll(requestEntity.getHeaders());

                            // 写入请求体
                            if (requestEntity.getBody() != null) {
                                new ObjectMapper().writeValue(request.getBody(), requestEntity.getBody());
                            }
                        },
                        response -> {
                            try (BufferedReader reader = new BufferedReader(new InputStreamReader(response.getBody()))) {
                                String line;
                                while ((line = reader.readLine()) != null) {
                                    log.info("line: {}", line);
                                    // 将每一行数据推送到前端
                                    emitter.send(SseEmitter.event().data(line));
                                }
                                // 完成推送
                                emitter.complete();
                            }
                            return null;
                        }
                );
            } catch (Exception e) {
                // 发生错误时推送错误信息
                emitter.completeWithError(e);
            } finally {
                executor.shutdown();
                log.info("对话结束...");
            }
        });
        // 关闭线程池
        executor.shutdown();
        log.info("对话完成...");
        return emitter;
    }

    /**
     * 清楚代码块
     * @param input
     * @return
     */
    private String cleanCodeBlock(String input) {
        // 正则表达式去除 ```json 和 ```（支持换行）
        return input.replaceAll("^```json\\s*|\\s*```$", "");
    }
}
